package br.usp.icmc.client.dao;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.criterion.Conjunction;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Subqueries;

import br.usp.icmc.client.entidades.Client;
import br.usp.icmc.client.entidades.KeyWord;
import br.usp.icmc.client.entidades.Service;
/******************************************************************
 * @author felipe
 *
 * <b> <br> Projeto: Aplicativo Cliente <br><b>
 *
 * Classe de acesso a tabela Service
 * 
 ******************************************************************/
public class ServiceDAO extends HibernateAbstractDAO<Service, Long>{

	ArrayList<String> keyword = new ArrayList<String>();
	private List<String> palavraChave;
	
	@Override
	public List<Service> select(String key) {
		return null;
		
	}
	
	/*********************************************************************
	 * Busca serviço pelo id
	 * 
	 * @param id
	 * 			ID do serviço desejado
	 * @return
	 * 			Retorna uma List com o serviço procurado
	 *********************************************************************/
	public List selectService(Long id){
		return getSession().createQuery("from Service s where s.idService=" + id ).list();
	}
	
	/********************************************************************
	 * Busca todos os serviços do sistema
	 * 
	 * @return
	 * 		Retorna uma List com todos os serviços
	 ********************************************************************/
	public List selectAll(){
		return getSession().createQuery("from Service").list();
	}

	/*********************************************************************
	 * Busca os serviços pelo nome
	 * 
	 * @param key
	 * 			Nome do serviço
	 * @return
	 * 			Retorna uma List com todos o serviço com tal nome
	 **********************************************************************/
	public List selectByName(String key) {
		return getSession().createQuery("from Service s where s.name like '%" + key +"%'").list();		
	}
	
	/***********************************************************************
	 * Busca os serviços de determinado provedor
	 * 
	 * @param email
	 * 			Email do Provedor
	 * @return
	 * 			Retorna uma List com todos os serviços do provedor
	 ************************************************************************/
	public List selectServiceProvider(String email){
		List services = getSession().createCriteria(Service.class)
				.add(Restrictions.eq("emailProvider", email))
				.addOrder(Order.asc("idService"))				
				.list();				
		return services;
	}
	
	/**
	 * Buscar serviço por nome
	 * 
	 * @param name
	 * @return
	 */
	public List serviceByName(String name){
		return getSession().createQuery("from Service s where s.name='" + name + "'").list();
	}
	
	
	/**
	 * Buscar serviço por palavra-chave
	 * 
	 * @param palavrasChave
	 * @return
	 */
	public List selectServiceWord(String word){
		//palavraChave.add(word);
		Criteria services = getSession().createCriteria(Service.class)
				.createAlias("keyWords", "words");
		
		Conjunction conj  = Restrictions.conjunction();		
		//Restrictions rest = null;
		
		//Iterator it = palavraChave.iterator();
		//while(it.hasNext()){
			String kwords = word;
			//rest.eq("words.word", kwords);
			//conj.add(Restrictions.eq("words.word", kwords));
			conj.add(Restrictions.ilike("words.word", kwords, MatchMode.ANYWHERE));
		//}						
		return services.add(conj)
				.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
				.list();
	}
	
	/**
	 * Buscar serviço por palavra-chave
	 * 
	 * @param palavrasChave
	 * @return
	 */

	public List selectByKeyWord(String palavrasChave){
		
		final String hql = "select distinct(s) from Service as s inner join s.keyWords as words where words.word in (:kword)";  
		  
		return getSession().createSQLQuery(hql)
		                              .setParameter("kword", palavrasChave)  
		                              .list();
	}
	
	/**
	 * Seleciona os serviços contratados por um cliente
	 * @param email
	 * @return
	 */
	public List selectServiceHired(String email){
		
		final String hql = "select distinct(s) from Service as s inner join s.contractClient as cli where cli.email in (:email)";  
		  
		return getSession().createQuery(hql)  
		                              .setParameter("email", email)  
		                              .list();
		
	}
	
/**
 * Seleciona as palavras-chave de um serviço	
 * @param idService
 * @return
 */
public List selectServicesKeyWord(Long idService){
		
		final String hql = "select distinct(w) from Service as s inner join s.keyWords as w where s.idService in (:idService)";  
		  
		return getSession().createQuery(hql)  
		                              .setParameter("idService", idService)  
		                              .list();
		
	}
	
}
